package com.kgc.est.controller;


import com.alibaba.fastjson.JSON;
import com.kgc.est.dto.UsersDto;
import com.kgc.est.feignService.UsersService;
import com.kgc.est.pojo.Users;
import com.kgc.est.request.LoginSmsReq;
import com.kgc.est.utils.Result;
import com.kgc.est.utils.UrlUtils;
import com.kgc.est.utils.weChat.WechatConfig;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户 前端控制器
 * </p>
 *
 * @author szq
 * @since 2021-10-19
 */
@RestController
@RequestMapping("/api/user")
public class UsersController {

    Logger log = LoggerFactory.getLogger(UsersController.class);

    //引入feign实例
    @Autowired
    private UsersService usersService;

    @Autowired
    private WechatConfig wechatConfig;

    @ApiOperation(value = "短信登录、注册接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone",value = "手机号",required = true,dataType = "String"),
            @ApiImplicitParam(name = "sms",value = "短息验证码",required = true,dataType = "String")
    })
    @PostMapping("/login/sms")
    public Result<Map<String,Object>> loginSms(String phone,String sms){
        return usersService.loginSms(new LoginSmsReq(phone,sms));
    }

    @GetMapping("/info")
    public Result<UsersDto> info(HttpServletRequest request){
        //请求头中获取token信息
        String token = request.getHeader("token");
        return usersService.info(token);
    }


    /**
     * 微信登录第一步：获取code
     *      用户在页面点击微信登录图标后，跳转到本方法
     *      然后由本方法重定向到微信提供的二维码页面
     * @param response
     */
    @ApiOperation(value = "微信登录、注册",produces = "application/json",
    notes = "使用微信扫码进行快速登录和注册。")
    @GetMapping("/login/wechat")
    public void wechatLogin(HttpServletResponse response){
        try {
        //拼接一个访问微信的路径
        StringBuilder openBuilder = new StringBuilder(wechatConfig.getOpen_url())
                .append("?").append("appid=").append(wechatConfig.getAppid())
                .append("&").append("redirect_uri=").append(wechatConfig.getRedirect_uri())
                .append("&").append("response_type=").append(wechatConfig.getResponse_type())
                .append("&").append("scope=").append(wechatConfig.getScope())
                .append("&").append("state=").append(wechatConfig.getState());
        //执行重定向操作，请求微信登录

            response.sendRedirect(openBuilder.toString());
        } catch (IOException e) {
            e.printStackTrace();
            log.info("唤起微信登陆页面失败：{}",e);
        }
    }


    /**
     * 微信登录第二步：
     *          1.接收微信返回的code
     *          2.通过跨服务访问工具向微信发送第二次请求
     *              https://api.weixin.qq.com/sns/oauth2/access_token?
     *              appid=APPID&
     *              secret=SECRET&
     *              code=CODE&
     *              grant_type=authorization_code
     *          3.微信会返回一个访问令牌access_token
     *              {
     *                   "access_token":"ACCESS_TOKEN",
     *                   "expires_in":7200,
     *                   "refresh_token":"REFRESH_TOKEN",
     *                   "openid":"OPENID",
     *                   "scope":"SCOPE",
     *                   "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
     *                }
     *           4.查询数据库中是否存储的有这个openid
     *              如果用户不存在
     *                  1.第三次向微信发送请求，需要携带访问令牌
     *                  2.拿到用户数据，封装，存储到数据库中
     *              如果用户存在
     *                  1.直接生成32位token作为key，用户信息JSON化后作为value存储到redis中
     *
     *
     * @param code
     * @param request
     * @param response
     */
    @GetMapping("/wechat/callback")
    public void wechatCallback(@RequestParam String code ,HttpServletRequest request,
                               HttpServletResponse response){
        //查看微信返回的code
        log.info("微信回调返回的code：{}",code);
        //拼接第二次访问微信的路径
        StringBuilder accessTokenBuilder = new StringBuilder(wechatConfig.getAccess_token_url())
                .append("?").append("appid=").append(wechatConfig.getAppid())
                .append("&").append("secret=").append(wechatConfig.getSecret())
                .append("&").append("code=").append(code)
                .append("&").append("grant_type=").append(wechatConfig.getGrant_type());
        //向微信发送第二次请求，并接收微信返回的数据
        String json = UrlUtils.loadURL(accessTokenBuilder.toString());

        //把这个json串转换成一个map集合
        Map map = JSON.parseObject(json, Map.class);
        log.info("第二次向微信发送请求返回的数据：{}",map);
        String access_token = map.get("access_token").toString();
        String openid = map.get("openid").toString();

        //调用服务提供者的方法进行用户查询，同时接收服务提供者返回的token数据
        Map<String, Object> resultMap = usersService.loginWechat(access_token, openid);
        log.info("用户登录成功，并向页面返回token：{}",resultMap.get("token"));

        try {
        //拼接前端页面路径和返回的数据
        String loginPage = wechatConfig.getSuccess_url()
                +"?token=" + resultMap.get("token") + "&userInfo="
                + URLEncoder.encode(resultMap.get("userInfo").toString(),"UTF-8");
            response.sendRedirect(loginPage);
        } catch (IOException e) {
            e.printStackTrace();
            log.info("微信回调错误：{}",e);
        }
        //然后重定向到页面
    }


}

